package com.vcc.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.data.entity.UserStatistics;
import com.vcc.data.mapper.UserStatisticsMapper;
import com.vcc.service.boss.request.userStatistics.UserStatisticsVo;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.UserStatisticsService;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.vcc.data.entity.table.BossUserTableDef.BOSS_USER;
import static com.vcc.data.entity.table.UserStatisticsTableDef.USER_STATISTICS;
import static com.vcc.data.entity.table.UserTableDef.USER;

@Service
public class UserStatisticsServiceImpl extends ServiceImpl<UserStatisticsMapper, UserStatistics> implements UserStatisticsService {
    @Override
    public Page<UserStatisticsVo> paging(Integer pageNumber, Integer pageSize, String startDate, String endDate, Long targetUserId, Long parentId, Long dealerId) {
        QueryChain<UserStatistics> queryChain = queryChain();
        queryChain.select(
                "user_id as userId",
                "SUM(register_count) as registerCount",
                "SUM(open_card_count) as openCardCount",
                "SUM(close_card_count) as closeCardCount",
                "SUM(verify_count) as verifyCount",
                "SUM(card_refund_count) as cardRefundCount",
                "SUM(card_consume_count) as cardConsumeCount",
                "SUM(card_refund_amount) as cardRefundAmount",
                "SUM(card_consume_amount) as cardConsumeAmount",
                "SUM(card_recharge_count) as cardRechargeCount",
                "SUM(card_reversal_count) as cardReversalCount",
                "SUM(card_withdraw_count) as cardWithdrawCount",
                "SUM(card_recharge_amount) as cardRechargeAmount",
                "SUM(card_reversal_amount) as cardReversalAmount",
                "SUM(card_withdraw_amount) as cardWithdrawAmount",
                "SUM(account_recharge_count) as accountRechargeCount",
                "SUM(account_withdraw_count) as accountWithdrawCount",
                "SUM(card_consume_fail_count) as cardConsumeFailCount",
                "SUM(account_recharge_amount) as accountRechargeAmount",
                "SUM(account_withdraw_amount) as accountWithdrawAmount",
                "SUM(card_consume_fail_amount) as cardConsumeFailAmount",
                "SUM(card_consume_success_count) as cardConsumeSuccessCount",
                "SUM(card_consume_success_amount) as cardConsumeSuccessAmount",
                "ANY_VALUE ( user.email ) AS account",
                "ANY_VALUE ( parent.email ) AS parentAccount",
                "ANY_VALUE ( dealer.email ) AS dealerAccount"
        );
        queryChain.leftJoin(USER).as("user").on(USER_STATISTICS.USER_ID.eq(USER.ID));
        queryChain.leftJoin(USER).as("parent").on(USER.PARENT_ID.eq(USER.as("parent").ID));
        queryChain.leftJoin(BOSS_USER).as("dealer").on(USER.as("user").BE_LONG_TO_DEALER.eq(BOSS_USER.ID));
        if (targetUserId != null) {
            queryChain.and(USER_STATISTICS.USER_ID.eq(targetUserId));
        }
        if (parentId != null) {
            queryChain.and(USER.PARENT_ID.eq(parentId));
        }
        if (!BossUserUtil.hasAllData()) {
            //没有所有权时需要 关联 经销商ID
            queryChain.and(BOSS_USER
                    .as("dealer").ID.eq(BossUserUtil.getId())
                    .or(BOSS_USER.as("dealer").PARENT_ID.eq(BossUserUtil.getId()))
            );
        } else {
            if (dealerId != null) {
                queryChain.and(BOSS_USER
                        .as("dealer").ID.eq(dealerId)
                        .or(BOSS_USER.as("dealer").PARENT_ID.eq(dealerId))
                );
            }
        }
        if (startDate != null && endDate != null) {
            queryChain.and(USER_STATISTICS.DATE.between(startDate, endDate));
        }
        queryChain.groupBy(USER_STATISTICS.USER_ID);
        return pageAs(
                Page.of(
                        pageNumber == null ? 1 : pageNumber,
                        pageSize == null ? 20 : pageSize
                ),
                queryChain,
                UserStatisticsVo.class);
    }

    @Override
    public List<String> existsByDates(String startDate,String endDate) {
        QueryChain<UserStatistics> queryChain = queryChain();
        queryChain.select("DISTINCT date");
        if (startDate != null && endDate != null) {
            queryChain.and(USER_STATISTICS.DATE.between(startDate, endDate));
        }
        return listAs(
                queryChain,
                String.class);
    }

    @Override
    public List<UserStatisticsVo> listByDate(String startDate, String endDate, Long targetUserId, Long dealerId) {
        QueryChain<UserStatistics> queryChain = queryChain();
        queryChain.select(
                "date",
                "SUM(register_count) as registerCount",
                "SUM(open_card_count) as openCardCount",
                "SUM(close_card_count) as closeCardCount",
                "SUM(verify_count) as verifyCount",
                "SUM(card_refund_count) as cardRefundCount",
                "SUM(card_consume_count) as cardConsumeCount",
                "SUM(card_refund_amount) as cardRefundAmount",
                "SUM(card_consume_amount) as cardConsumeAmount",
                "SUM(card_recharge_count) as cardRechargeCount",
                "SUM(card_reversal_count) as cardReversalCount",
                "SUM(card_withdraw_count) as cardWithdrawCount",
                "SUM(card_recharge_amount) as cardRechargeAmount",
                "SUM(card_reversal_amount) as cardReversalAmount",
                "SUM(card_withdraw_amount) as cardWithdrawAmount",
                "SUM(account_recharge_count) as accountRechargeCount",
                "SUM(account_withdraw_count) as accountWithdrawCount",
                "SUM(card_consume_fail_count) as cardConsumeFailCount",
                "SUM(account_recharge_amount) as accountRechargeAmount",
                "SUM(account_withdraw_amount) as accountWithdrawAmount",
                "SUM(card_consume_fail_amount) as cardConsumeFailAmount",
                "SUM(card_consume_success_count) as cardConsumeSuccessCount",
                "SUM(card_consume_success_amount) as cardConsumeSuccessAmount"
        );
        queryChain.leftJoin(USER).as("user").on(USER_STATISTICS.USER_ID.eq(USER.ID));
        queryChain.leftJoin(BOSS_USER).as("dealer").on(USER.as("user").BE_LONG_TO_DEALER.eq(BOSS_USER.ID));
        if (!BossUserUtil.hasAllData()) {
            //没有所有权时需要 关联 经销商ID
            queryChain.and(BOSS_USER
                    .as("dealer").ID.eq(BossUserUtil.getId())
                    .or(BOSS_USER.as("dealer").PARENT_ID.eq(BossUserUtil.getId()))
            );
        } else {
            if (dealerId != null) {
                queryChain.and(USER.as("user").BE_LONG_TO_DEALER.eq(dealerId));
            }
        }
        if (targetUserId != null) {
            queryChain.and(USER_STATISTICS.USER_ID.eq(targetUserId));
        }
        if (startDate != null && endDate != null) {
            queryChain.and(USER_STATISTICS.DATE.between(startDate, endDate));
        }
        queryChain.groupBy(USER_STATISTICS.DATE);
        queryChain.orderBy(USER_STATISTICS.DATE.asc());
        return listAs(
                queryChain,
                UserStatisticsVo.class);
    }


    @Override
    public Boolean existsByDate(String date) {
        return queryChain().and(USER_STATISTICS.DATE.eq(date)).exists();
    }

    @Override
    public String getLastDate() {
        return queryChain().select("MAX(date)").oneAsOpt(String.class).orElse(null);
    }
}
